package com.dongdongshop.service.impl;

import com.dongdongshop.pojo.TbItem;
import com.dongdongshop.pojo.TbOrderItem;
import com.dongdongshop.service.CartService;
import com.dongdongshop.service.ItemService;
import com.dongdongshop.vo.CartVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
@DubboService
public class CartServiceImpl implements CartService {

    @DubboReference
    private ItemService itemService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<CartVO> addGoodsToCartList(List<CartVO> cartList, Long itemId, Integer num) {

        //1.根据SKU的id，也就是itemId，查询我们的商品信息SKU信息
        TbItem item = itemService.selectById(itemId);
//        2.获取商家id
        String sellerId = item.getSellerId();
//        3.判断原来购物车中有没有购买过此商家的商品
        CartVO cartBySellerId = getCartBySellerId(cartList, sellerId);
//        4.如果没有的话，说明之前没有买过
        if (cartBySellerId == null){
            //4.1.新建一个购物车对象，并且把商品放进去
            //4.2.明细列表也得创建
            cartBySellerId = new CartVO();
            cartBySellerId.setSellerId(sellerId);
            cartBySellerId.setSellerName(item.getSeller());
//            创建明细列表
            List<TbOrderItem> orderItemList = new ArrayList<>();
            //创建明细对象
            TbOrderItem orderItem = createTbOrderItem(item, num);

            //将明细数据追加到 【明细列表中】
            orderItemList.add(orderItem);
            //将明细列表放到车里
            cartBySellerId.setOrderItemsList(orderItemList);
            //车放到cartList中
            cartList.add(cartBySellerId);
        }else {
            //5.如果之前买过此商家商品
//                5.1.虽然买过，但是现在要添加的购物车数据，不在原来的明细列表中
            List<TbOrderItem> orderItemList = cartBySellerId.getOrderItemsList();
            //判断明细是否存在
            TbOrderItem orderItemByitemId = getOrderItemByitemId(orderItemList, item.getId());
            if (orderItemByitemId == null){
                //5.1.1.我们只需要追加明细
                orderItemByitemId = createTbOrderItem(item,num);
                //将明细数据追加到 【明细列表中】
                orderItemList.add(orderItemByitemId);
            }else {
                //5.2。买过，而且有同一件商品
//                5.2.1.我们只需要修改数量，并且修改小计价格
                orderItemByitemId.setNum(orderItemByitemId.getNum() + num);
                orderItemByitemId.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * orderItemByitemId.getNum()));
                //如果计算完发现数量为0了，就相当于商品没买，就要从list里移除元素
                if (orderItemByitemId.getNum() <= 0){
                    orderItemList.remove(orderItemByitemId);
                }
                //当我们移除完之后，发现明细列表没有数据了，我们需要将这个购物车从【购物车列表】中移除
                if (orderItemList.size() <= 0){
                    cartList.remove(cartBySellerId);
                }
            }

        }
        return cartList;
    }

    /**
     * 根据商家id，从购物车列表中查询商家对象
     * @param cartList
     * @param sellerId
     * @return
     */
    private CartVO getCartBySellerId(List<CartVO> cartList, String sellerId){
        //findFirst():获取过滤后的第一个
        //orElse():如果有则返回值，没有则返回null
        return cartList.stream().filter(cartVO -> Objects.equals(cartVO.getSellerId(),sellerId)).findFirst().orElse(null);
    }

    /**
     * 根据商品的id，从明细列表中查询明细对象
     * @param orderItemList
     * @param itemId
     * @return
     */
    private TbOrderItem getOrderItemByitemId(List<TbOrderItem> orderItemList,Long itemId){
        return orderItemList.stream().filter(orderItem -> Objects.equals(itemId,orderItem.getItemId())).findFirst().orElse(null);
    }

    /**
     * 创建购物车明细对象
     * @param item
     * @param num
     * @return
     */
    private TbOrderItem createTbOrderItem(TbItem item,Integer num){
        //创建明细
        TbOrderItem orderItem = new TbOrderItem();
        orderItem.setSellerId(item.getSellerId());
        orderItem.setNum(num);//购买的数量
        orderItem.setItemId(item.getId());
        //计算总价格
        orderItem.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * orderItem.getNum()));
        orderItem.setGoodsId(item.getGoodsId());
        orderItem.setPicPath(item.getImage());
        orderItem.setPrice(item.getPrice());
        orderItem.setTitle(item.getTitle());
        return orderItem;
    }

    @Override
    public void setCartListToRedis(String username, List<CartVO> cartVOList) {
        redisTemplate.opsForHash().put("cartVOList",username,cartVOList);
        redisTemplate.boundHashOps("itemList").put(username,cartVOList);
    }

    @Override
    public List<CartVO> findCartListFromRedis(String username) {
        List<CartVO> cartVOList = (List<CartVO>) redisTemplate.opsForHash().get("cartVOList",username);
        if (cartVOList == null){
            cartVOList = new ArrayList<>();
        }
        return cartVOList;
    }

    @Override
    public List<CartVO> mergeCartList(List<CartVO> cartVOListRedis, List<CartVO> cartVOListCookie) {
        for (CartVO cartVO:cartVOListCookie) {
            //合并思路：需要校验当前循环的cart在另外一个购物车列表中有没有那个商家的购物车
            //如果没有，我们需要创建一个购物车，放到另一个购物车列表中
            //如果有，我们还需要看一下有没有买过同一件商品
            //如果没买过同一件商品，那么我们追加明细，如果买过，只需要修改总价格和数量
            //这个逻辑我们上面已经写过，因此不需要再写一遍，只需要调用一下即可
            for (TbOrderItem tbOrderItem: cartVO.getOrderItemsList()) {
                cartVOListRedis = addGoodsToCartList(cartVOListRedis, tbOrderItem.getItemId() , tbOrderItem.getNum());
            }
        }

        return cartVOListRedis;
    }
}
